export const GROUPING_BEGIN_JD = 1;
export const GROUPING_BEGIN_FUNC_CALC = 2
export const GROUPING_BEGIN_FUNC_CEIL= 3

export const GROUPING_BEGIN = 4;
export const IDENTIFIER = 5;
export const LITERAL = 6;
export const INFIX_OP = 7;
export const PREFIX_OP = 8;
export const GROUPING_END = 9;

function parseFloatValue(a){
    if(a.search(/%/) != -1){
        return a
    }

    if(a == 'SCREEN_WIDTH'){
        return "448";
    }
    if(a== 'SCREEN_HEIGHT'){
        return "879.3"
    }
    return a;
    //return parseFloat(a)
}

function parseVarValue(a) {
    if (a == "true") {
        return true
    }

    if (a == "false") {
        return false
    }
    return a
}

export class Tokenizer {

    static regExes:any[] = [

        // infix operator
        // +, -, *, /, %, &, |, ^, !, &&, ||, =, !=, ==, !==, ===, >, <, >=, >=, **, ??, ?, <<, >>, >>>, :, ~, ., .? and comma (,)
        // + and - are corrected to PREFIX_OP later, when they are not succeding an expression
        [INFIX_OP, 'index_op', /^([\<]{2}|[\>]{2,3}|[\*]{1,2}|\?\.|[\?]{1,2}|[\&]{1,2}|[\|]{1,2}|[\=]{2,3}|[\!][\=]{1,2}|[\>\<][\=]|[\+\-\/\%\|\^\>\<\=\,\:\.])/],

        // prefix operator: !, ~, (typeof and void are handled later)
        [PREFIX_OP, 'prefix_op', /^([\!\~])/],

        [LITERAL, 'chinese_writing', /[\u4E00-\u9FA5]+/],

        // number
        [LITERAL,  'literal_number', /^([-+]{0,1}(?:(?:[0-9]+[.][0-9]+)|(?:[0-9]+))[\%]{0,1})/, a => parseFloatValue(a)],

        [LITERAL,  'literal_number', /^(SCREEN_WIDTH|SCREEN_HEIGHT)/, a => parseFloatValue(a)],

        // string (single quotes)
        [LITERAL, 'literal_string_sing_quotes', /^'((?:(\\')|[^'])*)'/],

        // string (double quotes)
        [LITERAL, 'literal_string_double_quotes', /^"((?:(\\")|[^"])*)"/],

        [LITERAL, 'literal_string_unit', /^([#¥￥])/],

        // variable  (acually, identifier - https://developer.mozilla.org/en-US/docs/Glossary/Identifier)
        //[IDENTIFIER, 'variable', /^([a-zA-Z_$][a-zA-Z_$0-9]*)/],
        //Todo 此处去掉第一个$， 不要把$识别为字符串
        //[IDENTIFIER, 'variable', /^([a-zA-Z_][a-zA-Z_$0-9]*)/],

        //匹配$calc
        [GROUPING_BEGIN_FUNC_CALC, 'group_begin_func', /([$]calc\()/],

        //匹配ceil(
        [GROUPING_BEGIN_FUNC_CEIL, 'group_begin_func', /(ceil\()/],

        [GROUPING_BEGIN_FUNC_CEIL, 'group_begin_func', /([$]joint\()/],

        //优先级更高
        [IDENTIFIER, 'variable_wareInfo.name', /^([a-zA-Z]+[\.][a-zA-Z_0-9]+)/],

        [IDENTIFIER, 'variable_wareInfo[0].name', /^([a-zA-Z]+\[[0-9]\].[a-zA-Z_0-9]+)/],

        [IDENTIFIER, 'variable_name', /^([a-zA-Z_][a-zA-Z_0-9]*)/, a => parseVarValue(a)],

        //匹配${
        [GROUPING_BEGIN_JD, 'group_begin_jd', /^([$@]\{)/],

        // Group begin - (left pare / left bracket / left curly bracket)
        [GROUPING_BEGIN, 'group_begin',/^([\(\[\{])/],

        // Group end (right paren / right bracket / right curly bracket)
        [GROUPING_END, 'group_end', /^([\)\]\}])/],
    ]

    static isFunctionCall(token) {
        //Todo
        return false;
    }

    static isOperator(token) {
        return (token == INFIX_OP)
            || (token == PREFIX_OP)
            || (token == GROUPING_BEGIN)
            || (token == GROUPING_BEGIN_JD)
            || (token == GROUPING_BEGIN_FUNC_CALC
            || (token == GROUPING_BEGIN_FUNC_CEIL));
    }

    static isLiteral(token) {
        return (token == LITERAL)
    }

    /**
     * ([{等
     * @returns {boolean}
     */
    static isGroupBegin(token){
        return token == GROUPING_BEGIN || token == GROUPING_BEGIN_JD || token == GROUPING_BEGIN_FUNC_CALC || token == GROUPING_BEGIN_FUNC_CEIL;
    }

    /**
     * @[ $[
     */
    static isGroupJdBegin(token){
        return token == GROUPING_BEGIN_JD;
    }

    /**
     * }])
     * @param token
     * @returns {boolean}
     */
    static isGroupEnd(token){
        return token == GROUPING_END;
    }

    static isVarible(token){
        return token == IDENTIFIER || token == LITERAL || token == LITERAL;
    }

    /**
     * 此处注意顺序，一定是栈的参数在前， 读的参数在后
     * @param stackOperator
     * @param token
     * @returns {boolean}
     */
    static isPair(stackOperator: string, token:string){
        if((stackOperator == '(' && token == ')')){
            return true;
        }

        if(stackOperator == '{' && token == '}'){
            return true;
        }

        if(stackOperator == '[' && token == ']'){
            return true;
        }

        if(stackOperator == '${' && token == '}'){
            return true;
        }

        if(stackOperator == '@{' && token == '}'){
            return true;
        }

        if(stackOperator == '$calc(' && token ==')'){
            return true;
        }

        if(stackOperator == "ceil(" && token == ")"){
            return true;
        }

        if(stackOperator == '$joint(' && token ==')'){
            return true;
        }

        return false;
    }


}
